// 内容脚本 - 直接在页面中注入并执行
// 简化版本，减少依赖和通信问题

// 创建日志记录器
const logger = {
  log: (message) => {
    console.log('[智能答题助手]:', message)
    try {
      chrome.runtime.sendMessage({
        from: 'content',
        type: 'log',
        data: message
      })
    } catch (e) {
      console.error('发送日志失败:', e)
    }
  },
  warn: (message) => {
    console.warn('[智能答题助手]:', message)
    try {
      chrome.runtime.sendMessage({
        from: 'content',
        type: 'log',
        data: `警告: ${message}`
      })
    } catch (e) {
      console.error('发送警告日志失败:', e)
    }
  },
  error: (message) => {
    console.error('[智能答题助手]:', message)
    try {
      chrome.runtime.sendMessage({
        from: 'content',
        type: 'log',
        data: `错误: ${message}`
      })
    } catch (e) {
      console.error('发送错误日志失败:', e)
    }
  }
}

// 状态
let isRunning = false
let currentQuestion = {
  type: '',
  text: '',
  answer: '',
  status: 'idle'
}
let configs = null
let timeout = null

// 默认配置
const DEFAULT_CONFIG = {
  appConfig: {
    name: '默认配置',
    selector: '[class^="questionTypeTitle___"]',
    messages: [
      { role: 'system', content: '#你所有的回答都是JSON格式【你所有的回答都是JSON格式】' },
      { role: 'system', content: '不要多余解释！单选题多选题和判断题只要答案的选项即可（单选题answer字段是只有一个元素的数组，多选题answer字段是数组，判断题数组元素是正确或者是错误）,最终输出格式为:{ "answer": ["A","*"]  }' },
      { role: 'system', content: '不要多余解释！填空题一个问题可能有多个空要确保，一个填空标志为▁▁▁▁▁，或者识别填空项1,填空项2,填空项3...作为最终数组的length，不要多出数组！答案是数组{ "answer": ["填空答案一","二"]  }' }
    ],
    extraConfig: {
      model: 'Qwen/Qwen2.5-7B-Instruct',
      temperature: 0.3,
      top_p: 0.9
    }
  },
  modelConfig: {
    baseUrl: 'https://api.siliconflow.cn/v1/chat/completions',
    apiKey: '',
    name: '默认模型'
  }
}

// 初始化
async function initialize() {
  logger.log('初始化内容脚本')
  
  // 从存储加载配置
  try {
    const result = await new Promise((resolve) => {
      chrome.storage.sync.get(['appConfig', 'modelConfig'], resolve)
    })
    
    configs = {
      appConfig: result.appConfig || DEFAULT_CONFIG.appConfig,
      modelConfig: result.modelConfig || DEFAULT_CONFIG.modelConfig
    }
    logger.log('配置加载完成')
    
    // 如果没有配置，尝试从弹出窗口获取
    if (!result.appConfig || !result.modelConfig) {
      logger.log('未找到配置，尝试从弹出窗口获取')
      await requestConfigFromPopup()
    }
  } catch (error) {
    logger.error('加载配置失败: ' + error.message)
    configs = DEFAULT_CONFIG
  }
  
  // 设置消息监听器
  setupMessageListener()
}

// 从弹出窗口请求配置
async function requestConfigFromPopup() {
  try {
    chrome.runtime.sendMessage({
      from: 'content',
      action: 'requestConfig'
    })
  } catch (error) {
    logger.error('请求配置失败: ' + error.message)
  }
}

// 设置消息监听器
function setupMessageListener() {
  try {
    // 移除任何现有的监听器，避免重复
    chrome.runtime.onMessage.removeListener(handleMessage);
    
    // 添加新的消息监听器
    chrome.runtime.onMessage.addListener(handleMessage);
    logger.log('消息监听器设置完成');
  } catch (error) {
    logger.error('设置消息监听器失败: ' + error.message);
  }
}

// 消息处理函数 - 分离出来便于维护和测试
function handleMessage(message, sender, sendResponse) {
  try {
    const { action } = message;
    logger.log('收到消息: ' + action);
    
    // 使用消息处理映射表，避免大量if-else嵌套
    const handlers = {
      // 响应 ping 消息，确认内容脚本已加载
      ping: () => {
        sendResponse({ status: 'ok', loaded: true });
      },
      
      // 开始解题
      startSolving: () => {
        // 检查配置是否完整
        if (!configs?.modelConfig?.apiKey) {
          logger.error('未配置API密钥，无法开始解题');
          sendResponse({ success: false, error: '未配置API密钥' });
          return;
        }
        
        startSolving();
        sendResponse({ success: true });
      },
      
      // 停止解题
      stopSolving: () => {
        stopSolving();
        sendResponse({ success: true });
      },
      
      // 更新配置
      updateConfig: () => {
        configs = message.data;
        logger.log('配置已更新');
        sendResponse({ success: true });
      },
      
      // 获取状态
      getStatus: () => {
        sendResponse({ 
          isRunning, 
          currentQuestion,
          configs: {
            ...configs,
            modelConfig: configs?.modelConfig ? {
              ...configs.modelConfig,
              apiKey: configs.modelConfig.apiKey ? '[已隐藏]' : '未设置'
            } : null
          }
        });
      },
      
      // 测试连接
      testConnection: () => {
        testConnection()
          .then(result => sendResponse({ success: true, result }))
          .catch(error => sendResponse({ success: false, error: error.message }));
        return true; // 保持消息通道开放
      }
    };
    
    // 执行对应的处理函数
    if (handlers[action]) {
      // 如果处理函数返回true，表示需要保持消息通道开放
      return handlers[action]() || true;
    } else {
      logger.warn(`未知的消息动作: ${action}`);
      sendResponse({ success: false, error: '未知的消息动作' });
    }
    
    return true; // 默认保持消息通道开放
  } catch (error) {
    logger.error('消息处理错误: ' + error.message);
    sendResponse({ success: false, error: error.message });
    return true;
  }
}

// 测试连接
async function testConnection() {
  if (!configs?.modelConfig?.apiKey) {
    throw new Error('未配置API密钥')
  }
  
  const url = configs.modelConfig.baseUrl || 'https://api.siliconflow.cn/v1/chat/completions'
  const model = configs.appConfig?.extraConfig?.model || 'Qwen/Qwen2.5-7B-Instruct'
  
  const response = await fetch(url, {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${configs.modelConfig.apiKey}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      model,
      messages: [{ role: 'user', content: '测试连接' }],
      max_tokens: 5
    })
  })
  
  if (!response.ok) {
    const errorText = await response.text()
    throw new Error(`API连接测试失败: ${response.status} ${response.statusText} - ${errorText}`)
  }
  
  return { status: 'connected', url }
}

// 开始解题
function startSolving() {
  if (isRunning) return
  
  // 再次检查配置
  if (!configs?.modelConfig?.apiKey) {
    logger.error('未配置API密钥，无法开始解题')
    return
  }
  
  isRunning = true
  logger.log('开始解题')
  processNextQuestion()
}

// 停止解题
function stopSolving() {
  if (!isRunning) return
  
  isRunning = false
  logger.log('停止解题')
  
  if (timeout) {
    clearTimeout(timeout)
    timeout = null
  }
}

// 处理下一题
async function processNextQuestion() {
  if (!isRunning) return
  
  try {
    await findAndSolveQuestion()
  } catch (error) {
    logger.error('处理题目出错: ' + error.message)
  }
  
  // 安排下一题
  if (isRunning) {
    timeout = setTimeout(processNextQuestion, 2000)
  }
}

// 查找并解答题目
async function findAndSolveQuestion() {
  // 获取题目类型和内容
  const selector = configs?.appConfig?.selector || '[class^="questionTypeTitle___"]'
  const questionType = document.querySelector(selector)?.textContent?.trim().slice(2)
  const questionElement = document.querySelector('[class^="questionPart___"]')
  
  if (!questionElement) {
    logger.log('未找到题目')
    return
  }
  
  const questionText = questionElement.textContent.trim()
  
  // 更新当前问题
  currentQuestion = {
    type: questionType,
    text: questionText,
    answer: '',
    status: 'processing'
  }
  
  // 发送状态更新
  try {
    chrome.runtime.sendMessage({
      from: 'content',
      type: 'questionUpdate',
      data: currentQuestion
    })
  } catch (e) {
    console.error('发送问题状态失败:', e)
  }
  
  logger.log(`正在处理${questionType}: ${questionText.substring(0, 30)}...`)
  
  // 根据题型处理
  switch (questionType) {
    case '填空题':
      await handleInputQuestion(questionText)
      break
    case '简答题':
      await handleShortAnswerQuestion(questionText)
      break
    case '单选题':
    case '多选题':
      await handleChoiceQuestion(questionText)
      break
    case '判断题':
      await handleTrueFalseQuestion(questionText)
      break
    case '编程题':
      logger.log('暂不支持编程题')
      break
    default:
      logger.log(`未知题型: ${questionType}`)
  }
}

// 处理填空题
async function handleInputQuestion(text) {
  const answer = await fetchLLMAnswer(text)
  currentQuestion.answer = answer
  
  // 发送状态更新
  try {
    chrome.runtime.sendMessage({
      from: 'content',
      type: 'questionUpdate',
      data: currentQuestion
    })
  } catch (e) {
    console.error('发送问题状态失败:', e)
  }
  
  // 从JSON提取答案
  const jsonString = extractJSON(answer)
  let answerList = []
  
  if (jsonString) {
    try {
      const parsed = JSON.parse(jsonString)
      answerList = Array.isArray(parsed.answer) ? parsed.answer : [parsed.answer]
    } catch (error) {
      logger.error('解析JSON失败: ' + error.message)
    }
  }
  
  // 填写输入框
  const inputs = document.querySelectorAll('[class*="fillInput___"]')
  
  for (let i = 0; i < answerList.length && i < inputs.length; i++) {
    setInputValue(inputs[i], answerList[i])
    await delay(500)
  }
  
  goToNextQuestion()
}

// 处理简答题
async function handleShortAnswerQuestion(text) {
  const answer = await fetchLLMAnswer(text)
  currentQuestion.answer = answer
  
  // 发送状态更新
  try {
    chrome.runtime.sendMessage({
      from: 'content',
      type: 'questionUpdate',
      data: currentQuestion
    })
  } catch (e) {
    console.error('发送问题状态失败:', e)
  }
  
  // 从JSON提取答案
  const jsonString = extractJSON(answer)
  let answerText = ''
  
  if (jsonString) {
    try {
      const parsed = JSON.parse(jsonString)
      const answerArray = Array.isArray(parsed.answer) ? parsed.answer : [parsed.answer]
      answerText = answerArray.join(' ')
    } catch (error) {
      logger.error('解析JSON失败: ' + error.message)
    }
  }
  
  // 查找文本框并填写
  const textarea = document.querySelector('textarea')
  if (textarea) {
    setInputValue(textarea, answerText)
  }
  
  goToNextQuestion()
}

// 处理选择题
async function handleChoiceQuestion(text) {
  const answer = await fetchLLMAnswer(text)
  currentQuestion.answer = answer
  
  // 发送状态更新
  try {
    chrome.runtime.sendMessage({
      from: 'content',
      type: 'questionUpdate',
      data: currentQuestion
    })
  } catch (e) {
    console.error('发送问题状态失败:', e)
  }
  
  // 从JSON提取答案
  const jsonString = extractJSON(answer)
  let answerList = []
  
  if (jsonString) {
    try {
      const parsed = JSON.parse(jsonString)
      answerList = Array.isArray(parsed.answer) ? parsed.answer : [parsed.answer]
    } catch (error) {
      logger.error('解析JSON失败: ' + error.message)
    }
  }
  
  // 点击选项
  for (const option of answerList) {
    const elements = document.querySelectorAll('[class^="answerWrap___"] label:not([class*="ant-checkbox-wrapper-checked"]) .font16')
    const match = findElementBySimilarText(option, 0.1, elements)
    
    if (match) {
      match.click()
      await delay(300)
    }
  }
  
  goToNextQuestion()
}

// 处理判断题
async function handleTrueFalseQuestion(text) {
  const answer = await fetchLLMAnswer(text)
  currentQuestion.answer = answer
  
  // 发送状态更新
  try {
    chrome.runtime.sendMessage({
      from: 'content',
      type: 'questionUpdate',
      data: currentQuestion
    })
  } catch (e) {
    console.error('发送问题状态失败:', e)
  }
  
  // 从JSON提取答案
  const jsonString = extractJSON(answer)
  let answerList = []
  
  if (jsonString) {
    try {
      const parsed = JSON.parse(jsonString)
      answerList = Array.isArray(parsed.answer) ? parsed.answer : [parsed.answer]
    } catch (error) {
      logger.error('解析JSON失败: ' + error.message)
    }
  }
  
  // 点击选项
  for (const option of answerList) {
    const elements = document.querySelectorAll('[class^="answerWrap___"] label')
    const match = findElementBySimilarText(option, 0.1, elements)
    
    if (match) {
      match.click()
      await delay(300)
    }
  }
  
  goToNextQuestion()
}

// 获取LLM答案
async function fetchLLMAnswer(text) {
  if (!configs) {
    logger.error('配置未加载')
    return ''
  }
  
  if (!configs.modelConfig || !configs.modelConfig.apiKey) {
    logger.error('未配置API密钥')
    return ''
  }
  
  const apiKey = configs.modelConfig.apiKey
  const baseUrl = configs.modelConfig.baseUrl || 'https://api.siliconflow.cn/v1/chat/completions'
  const model = configs.appConfig?.extraConfig?.model || 'Qwen/Qwen2.5-7B-Instruct'
  const messages = [
    ...(configs.appConfig?.messages || DEFAULT_CONFIG.appConfig.messages),
    { role: 'user', content: text }
  ]
  
  logger.log('发送请求到: ' + baseUrl)
  
  try {
    const response = await fetch(baseUrl, {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${apiKey}`,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        model,
        messages,
        stream: true,
        temperature: configs.appConfig?.extraConfig?.temperature || 0.3,
        top_p: configs.appConfig?.extraConfig?.top_p || 0.9
      })
    })
    
    if (!response.ok) {
      const errorText = await response.text()
      throw new Error(`API请求失败: ${response.status} ${response.statusText} - ${errorText}`)
    }
    
    if (!response.body) {
      throw new Error('API响应没有内容')
    }
    
    // 处理流式响应
    return await processStream(response.body)
  } catch (error) {
    logger.error('获取LLM答案出错: ' + error.message)
    return ''
  }
}

// 处理流式响应
async function processStream(stream) {
  const reader = stream.getReader()
  const decoder = new TextDecoder('utf-8')
  let buffer = ''
  let result = ''
  
  try {
    while (true) {
      const { value, done } = await reader.read()
      if (done) break
      
      const chunk = decoder.decode(value, { stream: true })
      buffer += chunk
      
      const lines = buffer.split('\n')
      buffer = lines.pop() || ''
      
      for (const line of lines) {
        const trimmedLine = line.trim()
        if (!trimmedLine.startsWith('data: ')) continue
        
        const jsonStr = trimmedLine.slice(6).trim()
        if (!jsonStr || jsonStr === '[DONE]') continue
        
        try {
          const parsed = JSON.parse(jsonStr)
          
          if (!parsed.choices) continue
          
          for (let i = 0; i < parsed.choices.length; i++) {
            const choice = parsed.choices[i]
            if (!choice || !choice.delta) continue
            
            const content = choice.delta.content
            if (content) {
              result += content
              currentQuestion.answer = result
              
              // 发送状态更新
              try {
                chrome.runtime.sendMessage({
                  from: 'content',
                  type: 'questionUpdate',
                  data: currentQuestion
                })
              } catch (e) {
                // 忽略发送错误
              }
            }
          }
        } catch (err) {
          console.error('JSON解析错误:', err)
        }
      }
    }
    
    return result
  } catch (error) {
    logger.error('处理流出错: ' + error.message)
    return result
  } finally {
    reader.releaseLock()
  }
}

// 从文本中提取完整JSON对象
function extractJSON(text) {
  if (!text) return null
  
  const firstBrace = text.indexOf('{')
  if (firstBrace === -1) return null
  
  let braceCount = 0
  let jsonStr = ''
  let started = false
  
  for (let i = 0; i < text.length; i++) {
    const char = text[i]
    
    if (char === '{' && !started) {
      started = true
      braceCount = 1
      jsonStr += char
    } else if (started) {
      jsonStr += char
      
      if (char === '{') {
        braceCount++
      } else if (char === '}') {
        braceCount--
        
        if (braceCount === 0) {
          return jsonStr
        }
      }
    }
  }
  
  return null
}

// 前往下一题
function goToNextQuestion() {
  const nextBtn = [...document.querySelectorAll('span')].find(
    span => span.textContent.trim() === "下一题"
  )
  
  if (nextBtn) {
    nextBtn.click()
    currentQuestion.status = 'completed'
    
    // 发送状态更新
    try {
      chrome.runtime.sendMessage({
        from: 'content',
        type: 'questionUpdate',
        data: currentQuestion
      })
    } catch (e) {
      console.error('发送问题状态失败:', e)
    }
  } else {
    logger.log('未找到"下一题"按钮')
  }
}

// 通过相似文本查找元素
function findElementBySimilarText(targetText, threshold = 0.8, elements) {
  let bestMatch = null
  let bestScore = 0
  
  for (const el of elements) {
    const text = el.textContent.trim()
    const score = similarity(text, targetText)
    if (score > bestScore && score >= threshold) {
      bestScore = score
      bestMatch = el
    }
  }
  
  return bestMatch
}

// 计算文本相似度
function similarity(s1, s2) {
  if (!s1 || !s2) return 0
  s1 = s1.toLowerCase()
  s2 = s2.toLowerCase()
  const common = s1.split('').filter(c => s2.includes(c))
  return common.length / Math.max(s1.length, s2.length)
}

// 设置输入值
function setInputValue(input, value) {
  try {
    // 使用原生输入设置器绕过React合成事件
    const nativeInputValueSetter = Object.getOwnPropertyDescriptor(
      window.HTMLInputElement.prototype,
      "value"
    ).set
    
    nativeInputValueSetter.call(input, value)
    input.dispatchEvent(new Event('input', { bubbles: true }))
    input.dispatchEvent(new Event('focusout', { bubbles: true }))
  } catch (error) {
    logger.error('设置输入值出错: ' + error.message)
  }
}

// 延迟函数
function delay(ms) {
  return new Promise(resolve => setTimeout(resolve, ms))
}

// 检查是否在支持的网站上
function isSupportedWebsite() {
  return window.location.hostname.includes('educoder.net') || 
         window.location.hostname.includes('localhost')
}

// 仅在支持的网站上初始化
if (isSupportedWebsite()) {
  initialize()
  
  // 添加全局错误处理器
  window.addEventListener('error', (event) => {
    logger.error(`全局错误: ${event.message} at ${event.filename}:${event.lineno}:${event.colno}`)
  })
} 